//@ts-nocheck
/** 每次渲染都是独立的闭包
 每一次渲染(调用该组件函数运行)都有它自己的 Props and State (其实只是因为你每次setState时 都是传入的一个全新的对象 才每次渲染 state都不一样, 见下面例子)
 每一次渲染(调用该组件函数运行)都有它自己的事件处理函数

 alert会“捕获”我点击按钮时候的状态。
 我们的组件函数每次渲染都会被调用,但是每一次调用中number值都是常量,并且它被赋予了当前渲染中的状态值
 在单次渲染的范围内,props和state始终保持不变
 */
import React, {useState} from 'react';
let lastState;
export default () => {
  const [state, setState] = useState({number: 0});
  console.log('state === lastState:', state === lastState); // 你会发现永远为false,说明即使是对象类型,每次渲染时的state也不是同一个
  console.log('state.number:', state.number); //(你会发现即使点击的是 `用老状态setState`, 这里的state.number也是最新的
  lastState = state;
  const alertNumber = () => {
    setTimeout(() => {
      alert(state.number); //你会发现打出的是你当时点击时number的值 而不是现在number的值 (因为从作用域查找来说, 它查找到的state是本次render运行 useState 返回的那个state
      // 并且这种情况是无解的,如果你使用useState的话,并想打印其返回的state的话
    }, 3000);
  };

  return (
    <div>
      <p>{state.number}</p>
      <button onClick={() => setState({number: state.number + 1})}>+</button>

      {/*
          ↓但如果你这样返回状态, 它和上次的lastState比较就是相等的, 但这样做并不会触发ui渲染 (So 其实只是因为你每次setState时 都是传入的一个全新的对象 才每次渲染 state都不一样罢了)
          注：你想看到`state === lastState`的打印结果 你需要点击一次上面的普通的+1, 再点击↓的 用老状态setState+1 才会触发本组件的重新render(只会触发一次,要再想触发,需要重复上述步骤)
            并且即使会触发render, 但也不会真正重新渲染ui (只是让函数组件重新执行了一次罢了
      */}
      <button onClick={() => setState((state.number = state.number + 1, state))}>用老状态setState</button>

      <button onClick={alertNumber}>alert</button>
    </div>
  )
};
